package busquedas

import org.hibernate.Criteria
import aerolineasYVuelos.Aerolinea
import javax.persistence.GeneratedValue
import javax.persistence.Id
import javax.persistence.GenerationType
import javax.persistence.Inheritance
import javax.persistence.InheritanceType
import javax.persistence.Entity
import javax.persistence.DiscriminatorColumn
import javax.persistence.DiscriminatorType
import org.hibernate.criterion.Restrictions
import java.util.Date
import org.hibernate.criterion.Projections
import org.hibernate.criterion.Order


@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(      name="tipo_criterio",
  discriminatorType=DiscriminatorType.STRING      )
abstract class CriterioDeBusqueda {
	@Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    var id: Int = _
    def getId = id
    def setId(i: Int) { id = i }
	
	def activarFiltro(criteria: Criteria): Criteria
}

@Entity
class CriterioAerolinea extends CriterioDeBusqueda {
	var aerolineaId: Int = _
	def getAerolineaId: Int = aerolineaId
	def setAerolineaId(unAerolineaId: Int) { aerolineaId = unAerolineaId }
	
	def this(unAerolineaId: Int) {
	  this
	  setAerolineaId(unAerolineaId)
	}
	
	def activarFiltro(criteria: Criteria): Criteria = {
		criteria.add(Restrictions.eq("id", getAerolineaId))
		criteria
	}
}

@Entity
class CriterioOrigenDestino extends CriterioDeBusqueda {
	var origen: String = _
	def getOrigen: String = origen
	def setOrigen(unOrigen: String) { origen = unOrigen }
	
	var destino: String = _
	def getDestino: String = destino
	def setDestino(unDestino: String) { destino = unDestino }
	
	def this(origen: String, destino: String) {
	  this
	  setOrigen(origen)
	  setDestino(destino)
	}
	
	def activarFiltro(criteria: Criteria): Criteria = {
		criteria.createCriteria("tramos")
	    .add(Restrictions.like("origen", getOrigen))
	    .add(Restrictions.like("destino", getDestino))
	    criteria
	}
}

@Entity
class CriterioHoraSalida extends CriterioDeBusqueda{
  var miHoraSalida: Date = _ 
  def getMiHoraSalida : Date = { miHoraSalida}
  def setMiHoraSalida (unaHora : Date) { miHoraSalida  = unaHora }
  
  def this(horaSalida: Date) {
    this
    setMiHoraSalida(horaSalida)
  }

  def activarFiltro(criteria: Criteria): Criteria = {
	   criteria.createCriteria("tramos")
	   .add(Restrictions.eq("horaSalida", getMiHoraSalida))
	   criteria
  }
}

@Entity
class CriterioHoraLlegada extends CriterioDeBusqueda {
	var miHoraLlegada: Date = _
	def getMiHoraLlegada: Date = miHoraLlegada
	def setMiHoraLlegada(unaHoraLlegada: Date) { miHoraLlegada = unaHoraLlegada }
	
	def this(horaLlegada: Date) {
	  this
	  setMiHoraLlegada(horaLlegada)
	}
	
	def activarFiltro(criteria: Criteria): Criteria = {
		criteria.createCriteria("tramos")
	    .add(Restrictions.eq("horaLlegada", getMiHoraLlegada))
	    criteria
	}
}

@Entity
class CriterioDeOrdenamientoPorMenosEscalas extends CriterioDeBusqueda {
	def activarFiltro(criteria: Criteria): Criteria = {
//		criteria.createAlias("Vuelo.tramos", "tramosPorVuelo");
//		criteria.setProjection(Projections.projectionList.add(Projections.groupProperty("Vuelo.id"))
//		.add(Projections.count("tramosPorVuelo.id").as("cantidadDeTramosPorVuelo")))
//		criteria.addOrder(Order.asc("cantidadDeTramosPorVuelo"))
		criteria.addOrder(SizeOrder.asc("tramos"))
		criteria
	}
}

@Entity
class CriterioDeOrdenamientoPorDuracion extends CriterioDeBusqueda {
	def activarFiltro(criteria: Criteria): Criteria = {
		criteria.addOrder(Order.asc("duracionVuelo"))
		criteria
	}
}

@Entity
class CriterioDeOrdenamientoPorPrecio extends CriterioDeBusqueda {
	def activarFiltro(criteria: Criteria): Criteria = {
		criteria.addOrder(Order.asc("precioVuelo"))
		criteria
	}
}